package com.yuantu.judiciary.controller;

import com.google.gson.Gson;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.yuantu.judiciary.common.Response;
import com.yuantu.judiciary.common.ResponseFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 微信支付
 *
 * @author syw
 * @since 2023-08-10
 **/
@RestController
@RequestMapping(value = "/open/wx/pay")
@Api(tags = "微信支付接口")
@Slf4j
public class ApiWxPayController extends BaseController {

    /**
     * 商户号
     */
    public static String merchantId = "1624548283";
    /**
     * 商户API私钥路径
     */
//    @Value("${applet.private-key-path}")
//    public String privateKeyPath;
//    public static String privateKeyPath = "/Users/sherlock-s/Desktop/wechatPay/apiclient_key.pem";
//    public static String wechatPayCertificatePath = "/Users/sherlock-s/Desktop/wechatPay/apiclient_cert.pem";
    public static String privateKey = "-----BEGIN PRIVATE KEY-----\n" +
            "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDH2TGddjyEeiCy\n" +
            "nDiE6zaRYLJNVb/iMVxWcpfCgH9BfEEgr0OgV6knQlb4AWkPwSTekY1vbNdDKCCg\n" +
            "gwgF6V0Dz37cCkjtOItvy1ia0aJmqUsN8pg8l8wTPX+bl4IriHPYCVJGv5c20gHN\n" +
            "e/JPKps+BJOFgQRWWOlXNB3llAjFsM4VD+034HvAUdXy/tQgSSsCQrKYekkLVumA\n" +
            "gTc2xEOrFCij2zANSXUbpGvd9Y4mn8FHZ27wf691YdE/68kU2LVaL/IGVXp4TMZ6\n" +
            "jxX2BqghWE5rFpLhgdIjIE0hgXRqtPKNndWoaabgcJrvPzP2IIWdobUULBIjqYTT\n" +
            "+IKrjk3hAgMBAAECggEAN7TXG6lFnTfdvWvGZWabQ1LM4LmyTv6rWn1+x/zBfCOC\n" +
            "k/XGx/8na4YWb/MUsguIl3HDFvgj2Nhqn9NmfR9biiBgoD1NrrJAS91GyYD939f4\n" +
            "z957iQhXHlXaKCjHZBMZF3MhuA7Xu7Q2RGz0UhTySQtFg8U+zELkaCZi3wewmkn7\n" +
            "a/EEZWMOvCu29WL4tZRbpfj8s3ce6hw+fYjydtStADYWP+iAmH5jnvhl2dOT9UGb\n" +
            "i09blTJt3ix2EymkjrAamPJfngS914n+kr8Aibv5DSOA8dLUYYz/ZSRo2HwuF8/S\n" +
            "bvOSog25vNKAnIlhzlB2TawkbW8e3TbleS4DBn8BQQKBgQD+oH2uHZBWi+YhJEsp\n" +
            "OLvFI7wnu5Q9DxBCvxhfIpxDNVSEUQpT/Wq2qCwcioP8MEg/TITw4C/BgieLgPu2\n" +
            "SLITxc/4YMM+NgTbTUcsTKXZcstKQTIT1v+3UuXSW+UWZv5x7Hc3ZK6/mAXMo6M5\n" +
            "dcAVqvJItMLrBPwED5tEbkPYnQKBgQDI7RT13LeQVdnPIzRlG/K6FhED4LZ6u0PI\n" +
            "wWrcraUeC1Bzo/Gk8lf84GIZ0ahsHSpfcA25z1EtALQ+PWZ2yzBPgFmTvAtCMl0i\n" +
            "Njo+2pYwJQq3hNDYqqLTwzoA112bOdWjHr2M3W0MBM/2uVXvEhYLaad9gNNQw3Pl\n" +
            "xp0WCpbdFQKBgQDQXYk7eJnrGOSjbk3LV8/gjVOluAygwrjtxe8tuubg4L1e4epv\n" +
            "vMsc2hXu7TMApooYsod/jhXGZrnxoQVar7Z6E8ASYyyithXXWC/MApUdkqDlDODr\n" +
            "916fKElFkUmwwWuq0nTkcZHG26KzSZ2CoeckVBWchb+UDyokMJlAsHL4yQKBgHoT\n" +
            "YWrHwVeWcZFiaFEOG/lnssrSWsxSvqpYqZ6OegW5BhZcg1KeU0s24SOiuFuHlNkL\n" +
            "cat1BHL9PIWcNIb0iNOkvcf+tjBv/RnuLJFHqXxy5QH/VgxuECPtN26PazYGe4By\n" +
            "CuRtG/Xzbo8Op+Fq8a3ZcYPVI46sUdxHQeXEZUjJAoGAU/yXwb/7KwcfWL4YLSZz\n" +
            "RvCT0+vHTisQ4eDcUUk/A5P1dEXVPCWjIlpzEEkxE0fUvmKkgxUF3v1OC4GQBAZf\n" +
            "csGh/Aie6m1hpHlpQR2R25ePB51TYDcX/S5nFho/YF+iByRCoItQEwQp4yf2VHRM\n" +
            "p7RbBJgmw/6AvMt3TcPt2/M=\n" +
            "-----END PRIVATE KEY-----";

    /**
     * 商户证书序列号
     */
    public static String merchantSerialNumber = "7105493EC573E58D3B344CC26B23A91827BD62BA";
    /**
     * 商户APIV3密钥
     */
    public static String apiV3Key = "5lbkidpdepm1r8rhkd4i9plmhd32sg7i";
    /**
     * appid
     */
    private static String appid = "wxeccb8103bee7b465";


    public static Config config;

    Gson gson = new Gson();

    public void getConfig() {
        if (config == null) {
//            String path = privateKeyPath.substring("classpath:".length());
//            InputStream is = PropertiesUtil.class.getClassLoader().getResourceAsStream(path);
//            String privateKey = getFileContent(is);


            config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKey(privateKey)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
        }
    }

    public static String getFileContent(InputStream is) {
        try {
            int length = is.available();
            byte[] bytes = new byte[length];
            is.read(bytes);
            is.close();
            String str = new String(bytes, StandardCharsets.UTF_8);
            return str;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    @ApiOperation(value = "创建订单")
    @GetMapping("/create/order")
    public Response<String> createOrder() {
        getConfig();
        JsapiService service = new JsapiService.Builder().config(config).build();
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(1);
        request.setAmount(amount);
        request.setAppid(appid);
        request.setMchid(merchantId);
        request.setDescription("测试商品标题");
        request.setNotifyUrl("https://cxb.learncoder.com:8901/api/open/wx/pay/notify");
//        request.setNotifyUrl("https://admin.njxnet.com:8901/api/open/wx/pay/notify");
        String tradeNo = UUID.randomUUID().toString().replace("-", "");
        request.setOutTradeNo(tradeNo);
        Payer payer = new Payer();
        payer.setOpenid("oErp060K5_MHQBRnVLYCJ3epUgF8");
        request.setPayer(payer);
        PrepayResponse response = service.prepay(request);
        log.info("创建订单号: {}, 微信预支付订单号: {}", tradeNo, response.getPrepayId());
        return ResponseFactory.okResponse(gson.toJson(response));
    }

    @ApiOperation(value = "查看订单")
    @GetMapping("/query/order")
    public Response<String> queryOrder(@RequestParam String outTradeNo) {
        getConfig();
        JsapiService service = new JsapiService.Builder().config(config).build();
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(merchantId);
        request.setOutTradeNo(outTradeNo);
        Transaction transaction = service.queryOrderByOutTradeNo(request);
        return ResponseFactory.okResponse(gson.toJson(transaction));
    }

    @ApiOperation(value = "关闭订单")
    @GetMapping("/close/order")
    public Response<String> closeOrder(@RequestParam String outTradeNo) {
        getConfig();
        JsapiService service = new JsapiService.Builder().config(config).build();
        CloseOrderRequest request = new CloseOrderRequest();
        request.setMchid(merchantId);
        request.setOutTradeNo(outTradeNo);
        service.closeOrder(request);
        return ResponseFactory.okResponse("关闭订单: " + outTradeNo);
    }

    @ApiOperation(value = "回调接口")
    @PostMapping("/notify")
    public Response<Map> callOrder(HttpServletRequest request) throws IOException {
        getConfig();
        BufferedReader br = request.getReader();
        String str = null;
        StringBuilder sb = new StringBuilder();
        while ((str = br.readLine())!=null) {
            sb.append(str);
        }
//        // 构建request，传入必要参数
//        NotificationRequest requests = new NotificationRequest.Builder()
//                .withSerialNumber(request.getHeader("Wechatpay-Serial"))
//                .withNonce(request.getHeader("Wechatpay-Nonce"))
//                .withTimestamp(request.getHeader("Wechatpay-Timestamp"))
//                .withSignature(request.getHeader("Wechatpay-Signature"))
//                .withBody(String.valueOf(sb))
//                .build();

        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String signature = request.getHeader("Wechatpay-Signature");
        String signType = request.getHeader("Wechatpay-Signature-Type");
        String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");



        // 构造 RequestParam
        com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.RequestParam.Builder()
                .serialNumber(wechatPayCertificateSerialNumber)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .body(String.valueOf(sb))
                .build();

        log.info("支付回调构造参数: {}", sb);

        // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
        // 没有的话，则构造一个
//        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
//                .merchantId(merchantId)
//                .privateKeyFromPath(privateKeyPath)
//                .merchantSerialNumber(merchantSerialNumber)
//                .apiV3Key(apiV3Key)
//                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser((NotificationConfig) config);

        // 以支付通知回调为例，验签、解密并转换成 Transaction
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        log.info("支付回调解析结果: {}", transaction.toString());
        Map<String,Object> map = new HashMap<>();
        if (transaction.getTradeState().equals("SUCCESS")) {


            //code 退款码请前往微信支付文档查询
            map.put("code","SUCCESS");
            map.put("message", "成功");
        } else {
            map.put("code","FAIL");
            map.put("message", transaction.getTradeState());
        }
        return ResponseFactory.okResponse(map);
    }

    @ApiOperation(value = "获取下单参数")
    @GetMapping("/get/param")
    public Response<String> getParam(@RequestParam String outTradeNo) {
        getConfig();
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(1);
        request.setAmount(amount);
        request.setAppid(appid);
        request.setMchid(merchantId);
        request.setDescription("测试商品标题");
//        request.setNotifyUrl("https://cxb.learncoder.com:8901/api/open/wx/pay/notify");
        request.setNotifyUrl("https://admin.njxnet.com:8901/api/open/wx/pay/notify");
        request.setOutTradeNo(outTradeNo);
        Payer payer = new Payer();
        payer.setOpenid("oErp060K5_MHQBRnVLYCJ3epUgF8");
        request.setPayer(payer);
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        log.info("创建订单号: {}, 下单参数: {}", outTradeNo, response.toString());
        return ResponseFactory.okResponse(gson.toJson(response));
    }









}
